/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package ec.edu.ucuenca.pagina_asos.controller;

import ec.edu.ucuenca.pagina_asos.controller.exceptions.NonexistentEntityException;
import ec.edu.ucuenca.pagina_asos.controller.exceptions.RollbackFailureException;
import ec.edu.ucuenca.pagina_asos.controller.util.EntityManagerUtil;
import ec.edu.ucuenca.pagina_asos.entity.Documento;
import ec.edu.ucuenca.pagina_asos.entity.Escuela;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import ec.edu.ucuenca.pagina_asos.entity.Publicidad;
import java.util.ArrayList;
import java.util.List;
import ec.edu.ucuenca.pagina_asos.entity.Foro;
import ec.edu.ucuenca.pagina_asos.entity.Galeria;
import ec.edu.ucuenca.pagina_asos.entity.Persona;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.transaction.UserTransaction;

/**
 *
 * @author Marcelo
 */
public class EscuelaJpaController implements Serializable {

    public EscuelaJpaController(){
        
    }
    private UserTransaction utx = null;
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return EntityManagerUtil.get().createEntityManager();
    }

    public void create(Escuela escuela) throws RollbackFailureException, Exception {
        if (escuela.getPublicidades() == null) {
            escuela.setPublicidades(new ArrayList<Publicidad>());
        }
        if (escuela.getForos() == null) {
            escuela.setForos(new ArrayList<Foro>());
        }
        if (escuela.getGalerias() == null) {
            escuela.setGalerias(new ArrayList<Galeria>());
        }
        EntityManager em = null;
        try {
            utx.begin();
            em = getEntityManager();
            List<Publicidad> attachedPublicidades = new ArrayList<Publicidad>();
            for (Publicidad publicidadesPublicidadToAttach : escuela.getPublicidades()) {
                publicidadesPublicidadToAttach = em.getReference(publicidadesPublicidadToAttach.getClass(), publicidadesPublicidadToAttach.getId());
                attachedPublicidades.add(publicidadesPublicidadToAttach);
            }
            escuela.setPublicidades(attachedPublicidades);
            List<Foro> attachedForos = new ArrayList<Foro>();
            for (Foro forosForoToAttach : escuela.getForos()) {
                forosForoToAttach = em.getReference(forosForoToAttach.getClass(), forosForoToAttach.getId());
                attachedForos.add(forosForoToAttach);
            }
            escuela.setForos(attachedForos);
            List<Galeria> attachedGalerias = new ArrayList<Galeria>();
            for (Galeria galeriasGaleriaToAttach : escuela.getGalerias()) {
                galeriasGaleriaToAttach = em.getReference(galeriasGaleriaToAttach.getClass(), galeriasGaleriaToAttach.getId());
                attachedGalerias.add(galeriasGaleriaToAttach);
            }
            escuela.setGalerias(attachedGalerias);
            em.persist(escuela);
            for (Publicidad publicidadesPublicidad : escuela.getPublicidades()) {
                Escuela oldEscuelaOfPublicidadesPublicidad = publicidadesPublicidad.getEscuela();
                publicidadesPublicidad.setEscuela(escuela);
                publicidadesPublicidad = em.merge(publicidadesPublicidad);
                if (oldEscuelaOfPublicidadesPublicidad != null) {
                    oldEscuelaOfPublicidadesPublicidad.getPublicidades().remove(publicidadesPublicidad);
                    oldEscuelaOfPublicidadesPublicidad = em.merge(oldEscuelaOfPublicidadesPublicidad);
                }
            }
            for (Foro forosForo : escuela.getForos()) {
                Escuela oldEscuelaOfForosForo = forosForo.getEscuela();
                forosForo.setEscuela(escuela);
                forosForo = em.merge(forosForo);
                if (oldEscuelaOfForosForo != null) {
                    oldEscuelaOfForosForo.getForos().remove(forosForo);
                    oldEscuelaOfForosForo = em.merge(oldEscuelaOfForosForo);
                }
            }
            for (Galeria galeriasGaleria : escuela.getGalerias()) {
                Escuela oldEscuelaOfGaleriasGaleria = galeriasGaleria.getEscuela();
                galeriasGaleria.setEscuela(escuela);
                galeriasGaleria = em.merge(galeriasGaleria);
                if (oldEscuelaOfGaleriasGaleria != null) {
                    oldEscuelaOfGaleriasGaleria.getGalerias().remove(galeriasGaleria);
                    oldEscuelaOfGaleriasGaleria = em.merge(oldEscuelaOfGaleriasGaleria);
                }
            }
            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Escuela escuela) throws NonexistentEntityException, RollbackFailureException, Exception {
        EntityManager em = null;
        try {
            utx.begin();
            em = getEntityManager();
            Escuela persistentEscuela = em.find(Escuela.class, escuela.getId());
            List<Publicidad> publicidadesOld = persistentEscuela.getPublicidades();
            List<Publicidad> publicidadesNew = escuela.getPublicidades();
            List<Foro> forosOld = persistentEscuela.getForos();
            List<Foro> forosNew = escuela.getForos();
            List<Galeria> galeriasOld = persistentEscuela.getGalerias();
            List<Galeria> galeriasNew = escuela.getGalerias();
            List<Publicidad> attachedPublicidadesNew = new ArrayList<Publicidad>();
            for (Publicidad publicidadesNewPublicidadToAttach : publicidadesNew) {
                publicidadesNewPublicidadToAttach = em.getReference(publicidadesNewPublicidadToAttach.getClass(), publicidadesNewPublicidadToAttach.getId());
                attachedPublicidadesNew.add(publicidadesNewPublicidadToAttach);
            }
            publicidadesNew = attachedPublicidadesNew;
            escuela.setPublicidades(publicidadesNew);
            List<Foro> attachedForosNew = new ArrayList<Foro>();
            for (Foro forosNewForoToAttach : forosNew) {
                forosNewForoToAttach = em.getReference(forosNewForoToAttach.getClass(), forosNewForoToAttach.getId());
                attachedForosNew.add(forosNewForoToAttach);
            }
            forosNew = attachedForosNew;
            escuela.setForos(forosNew);
            List<Galeria> attachedGaleriasNew = new ArrayList<Galeria>();
            for (Galeria galeriasNewGaleriaToAttach : galeriasNew) {
                galeriasNewGaleriaToAttach = em.getReference(galeriasNewGaleriaToAttach.getClass(), galeriasNewGaleriaToAttach.getId());
                attachedGaleriasNew.add(galeriasNewGaleriaToAttach);
            }
            galeriasNew = attachedGaleriasNew;
            escuela.setGalerias(galeriasNew);
            escuela = em.merge(escuela);
            for (Publicidad publicidadesOldPublicidad : publicidadesOld) {
                if (!publicidadesNew.contains(publicidadesOldPublicidad)) {
                    publicidadesOldPublicidad.setEscuela(null);
                    publicidadesOldPublicidad = em.merge(publicidadesOldPublicidad);
                }
            }
            for (Publicidad publicidadesNewPublicidad : publicidadesNew) {
                if (!publicidadesOld.contains(publicidadesNewPublicidad)) {
                    Escuela oldEscuelaOfPublicidadesNewPublicidad = publicidadesNewPublicidad.getEscuela();
                    publicidadesNewPublicidad.setEscuela(escuela);
                    publicidadesNewPublicidad = em.merge(publicidadesNewPublicidad);
                    if (oldEscuelaOfPublicidadesNewPublicidad != null && !oldEscuelaOfPublicidadesNewPublicidad.equals(escuela)) {
                        oldEscuelaOfPublicidadesNewPublicidad.getPublicidades().remove(publicidadesNewPublicidad);
                        oldEscuelaOfPublicidadesNewPublicidad = em.merge(oldEscuelaOfPublicidadesNewPublicidad);
                    }
                }
            }
            for (Foro forosOldForo : forosOld) {
                if (!forosNew.contains(forosOldForo)) {
                    forosOldForo.setEscuela(null);
                    forosOldForo = em.merge(forosOldForo);
                }
            }
            for (Foro forosNewForo : forosNew) {
                if (!forosOld.contains(forosNewForo)) {
                    Escuela oldEscuelaOfForosNewForo = forosNewForo.getEscuela();
                    forosNewForo.setEscuela(escuela);
                    forosNewForo = em.merge(forosNewForo);
                    if (oldEscuelaOfForosNewForo != null && !oldEscuelaOfForosNewForo.equals(escuela)) {
                        oldEscuelaOfForosNewForo.getForos().remove(forosNewForo);
                        oldEscuelaOfForosNewForo = em.merge(oldEscuelaOfForosNewForo);
                    }
                }
            }
            for (Galeria galeriasOldGaleria : galeriasOld) {
                if (!galeriasNew.contains(galeriasOldGaleria)) {
                    galeriasOldGaleria.setEscuela(null);
                    galeriasOldGaleria = em.merge(galeriasOldGaleria);
                }
            }
            for (Galeria galeriasNewGaleria : galeriasNew) {
                if (!galeriasOld.contains(galeriasNewGaleria)) {
                    Escuela oldEscuelaOfGaleriasNewGaleria = galeriasNewGaleria.getEscuela();
                    galeriasNewGaleria.setEscuela(escuela);
                    galeriasNewGaleria = em.merge(galeriasNewGaleria);
                    if (oldEscuelaOfGaleriasNewGaleria != null && !oldEscuelaOfGaleriasNewGaleria.equals(escuela)) {
                        oldEscuelaOfGaleriasNewGaleria.getGalerias().remove(galeriasNewGaleria);
                        oldEscuelaOfGaleriasNewGaleria = em.merge(oldEscuelaOfGaleriasNewGaleria);
                    }
                }
            }
            utx.commit();
        } catch (Exception ex) {
            try {
                utx.rollback();
            } catch (Exception re) {
                throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
            }
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Long id = escuela.getId();
                if (findEscuela(id) == null) {
                    throw new NonexistentEntityException("The escuela with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Escuela> findEscuelaEntities() {
        return findEscuelaEntities(true, -1, -1);
    }

    public List<Escuela> findEscuelaEntities(int maxResults, int firstResult) {
        return findEscuelaEntities(false, maxResults, firstResult);
    }

    public List<Persona> obtenerDirectorio(Escuela escuela) {
        EntityManager em = getEntityManager();
        try {
            Query q = em.createQuery("select object(p) from Persona p where p.cargo is not null and p.escuela.id=:idEscuela");
            q.setParameter("idEscuela", escuela.getId());
           
            List<Persona> lista = q.getResultList();
            if (lista == null ){
                lista = new ArrayList<Persona>();
            }
            return lista;
        } finally {
            em.close();
        }        
        
    }

    public List<Documento> obtenerVideos(Galeria galeria) {
        EntityManager em = getEntityManager();
        try {
            Query q = em.createQuery("select object(d) from Documento d where d.tipo = 1 and d.galeria.id=:idgaleria order by d.fecha desc");
            q.setParameter("idgaleria", galeria.getId());
           
            List<Documento> lista = q.getResultList();
            if (lista == null ){
                lista = new ArrayList<Documento>();
            }
            return lista;
        } finally {
            em.close();
        }        
    }
    
    public List<Documento> obtenerFotos(Galeria galeria) {
        EntityManager em = getEntityManager();
        try {
            Query q = em.createQuery("select object(d) from Documento d where d.tipo = 0 and d.galeria.id=:idgaleria order by d.fecha desc");
            q.setParameter("idgaleria", galeria.getId());
           
            List<Documento> lista = q.getResultList();
            if (lista == null ){
                lista = new ArrayList<Documento>();
            }
            return lista;
        } finally {
            em.close();
        }        
    }
    
    public List<Galeria> obtenerGalerias(Escuela escuela) {
        EntityManager em = getEntityManager();
        try {
            Query q = em.createQuery("select object(g) from Galeria g where g.escuela.id=:id order by g.nombre asc");
            q.setParameter("id", escuela.getId());
           
            List<Galeria> lista = q.getResultList();
            if (lista == null ){
                lista = new ArrayList<Galeria>();
            }
            return lista;
        } finally {
            em.close();
        }        
    }
    
    public Escuela findEscuela(String subdominio) {
        EntityManager em = getEntityManager();
        try {
            Query q = em.createQuery("select e from Escuela e where e.dominio like :subdominio");
            q.setParameter("subdominio", subdominio+".%");
            
            List<Escuela> lista = q.getResultList();
            if (lista != null && lista.size() > 0) {
                return lista.get(0);
            }
            return null;
        } finally {
            em.close();
        }
    }
    
    
    
    public List<Escuela> findEscuelaEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Escuela.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Escuela findEscuela(Long id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Escuela.class, id);
        } finally {
            em.close();
        }
    }

    public int getEscuelaCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Escuela> rt = cq.from(Escuela.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
